#include "game.h"
#include "utils.h"
#include "mesh.h"
#include "texture.h"
#include "shader.h"
#include "TextureManager.h"
#include "MeshManager.h"
#include "EntityMesh.h"
#include "EntityCamera.h"
#include "BulletManager.h"
#include "Plane.h"
#include "Controller.h"
#include "World.h"
#include "Helice.h"

World* world;

EntityCamera* cam;
EntityMesh* terrain = NULL;
Controller* player = NULL;
EntityMesh* sky = NULL;
Plane* bomber = NULL;
Controller* enemy;
Plane* plane;
Helice* helice;

enum Cam_position { CABINA, COLA};
enum Cam_type{ FRONT, RIGHT, LEFT, BACK};

Cam_position cam_pos;
Cam_type cam_active;

float time_elapsed;
float time;

float angle = 0;

TextureManager* tex_manager;
MeshManager* mesh_manager;

Camera* cams[8];
void updateCams();

Game::Game()
{
	// initialize attributes
	// Warning: DO NOT CREATE STUFF HERE, USE THE INIT 
	// things create here cannot access opengl

	keystate = NULL;
	mouse_locked = false;
}

//Here we have already GL working, so we can create meshes and textures
void Game::init(void)
{
	Shader::init();
	world = World::getInstance();
	std::cout << "initiating game..." << std::endl;

	//OpenGL flags
	glEnable( GL_CULL_FACE ); //render both sides of every triangle
	glEnable( GL_DEPTH_TEST ); //check the occlusions using the Z buffer
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	//glEnable( GL_BLEND );


	/*
	//create our camera
	for(int c = 0; c < 8; ++c){
		cams[c] = new Camera();
		cams[c]->lookAt(Vector3(0,250,250),Vector3(0,0,0), Vector3(0,1,0)); //position the camera and point to 0,0,0
		cams[c]->setPerspective(70,WINDOW_WIDTH/(float)WINDOW_HEIGHT,0.1,10000); //set the projection, we want to be perspective
	}
	*/

	cam = new EntityCamera();
	world->activeCam = cam;
	tex_manager = TextureManager::getInstance();
	mesh_manager = MeshManager::getInstance();

	helice = new Helice();
	helice->mesh = mesh_manager->get("helice/helice.ASE");
	helice->texture = tex_manager->get("helice/helice.tga");
	helice->model.setRotation(180*DEG2RAD, Vector3(1,0,0));
	helice->model.scalar(2,2.25);
	helice->model.traslate(0,-2.6,0);

	plane = new Plane();
	plane->mesh = mesh_manager->get("spitfire/spitfire.ASE");
	plane->texture = tex_manager->get("spitfire/spitfire_color_spec.tga");
	plane->addChild(helice);
	plane->helice=helice;
	world->addChild(plane);
	//plane->model.setRotation(90*DEG2RAD, Vector3());
	

	SDL_ShowCursor(!mouse_locked); //hide or show the mouse

	plane->model.m[0]= 0.999846;
	plane->model.m[1]=0.0168925;
	plane->model.m[2]=0.00817866;
	plane->model.m[3]=0;
	plane->model.m[4]=0.0723842;
	plane->model.m[5]=0;
	plane->model.m[6]=-0.998524;
	plane->model.m[7]=0;
	plane->model.m[8]=-0.0171701;
	plane->model.m[9]=0.998416;
	plane->model.m[10]=0.0540604;
	plane->model.m[11]=0;
	plane->model.m[12]=-1297;
	plane->model.m[13]=4;
	plane->model.m[14]=-1538;
	plane->model.m[15]=1;

	//plane->model.setTranslation(-1315.49, -3.76501,-1988.33);
	//plane->model.rotate(-90*DEG2RAD,Vector3(0,1,0));
	//plane->model.setTranslation(0,400,0);
	
	//m_player.rotateLocal(90*DEG2RAD, Vector3(1,0,0));
	
	terrain = new EntityMesh();

	terrain->mesh = mesh_manager->get("terrain_airport/terrain_airport.Ase");
	terrain->texture = tex_manager->get("terrain_airport/terrain_airport.tga");

	terrain->model.setRotation(90*DEG2RAD, Vector3(1,0,0));
	world->addChild(terrain);

	sky = new EntityMesh();
	sky->model.setRotation(90*DEG2RAD, Vector3(1,0,0));
	sky->mesh = mesh_manager->get("cielo/cielo.ASE");
	sky->texture = tex_manager->get("cielo/cielo.tga");
	//world->addChild(sky);

	cam_pos = COLA;
	cam_active = FRONT;

	player = new Controller();
	player->player = plane;
	world->player = player;

	

	bomber = new Plane();
	bomber->model.setRotation(90*DEG2RAD, Vector3(1,0,0));
	bomber->model.traslate(0,200,0);
	bomber->mesh = mesh_manager->get("spitfire/spitfire.ASE");
	bomber->texture = tex_manager->get("spitfire/spitfire_color_spec.tga");
	bomber->addChild(helice);
	world->enemy = bomber;
	world->addChild(bomber);

	world->pos=terrain;

	//plane->addChild(cam);
plane->addChild(cam);


	

}


//what to do when the image has to be draw
void Game::render(void)
{
	
	//set the clear color (the background color)
	glClearColor(0.0, 0.0, 0.0, 1.0);

	// Clear the window and the depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	world->render();

	if(cam_pos == COLA){

	}

	/*
	plane->render();
	bomber->render();
	terrain->render();
	sky->render();

	BulletManager::getInstance()->render();
	*/
	/*
	plane->mesh->collision_model->setTransform(plane->model.m);
	terrain->mesh->collision_model->setTransform(terrain->model.m);
	float pointCollision[3], t1[9],t2[9];
	if(plane->mesh->collision_model->collision(terrain->mesh->collision_model,-1,0,0)==true){
            std::cout << "PointSpitfireContact: " << std::endl;
            plane->mesh->collision_model->getCollisionPoint(pointCollision,true);
            plane->mesh->collision_model->getCollidingTriangles(t1,t2,true);
            for(int i=0;i<3;i++) std::cout << pointCollision[i] << std::endl; 
    }
	int collisions;
	if(collisions = BulletManager::getInstance()->collides(terrain)){
		std::cout << collisions << " Bullets collides with terrain" << std::endl;
		std::cout<< BulletManager::getInstance()->bullets.size() << " bullets" << std::endl;
	}
	*/
	//swap between front buffer and back buffer
	SDL_GL_SwapBuffers();
}

void Game::update(double seconds_elapsed)
{
	time_elapsed = (float) seconds_elapsed;
	time += (float)seconds_elapsed;
	world->update(time_elapsed);
}

//Keyboard event handler (sync input)
void Game::onKeyPressed( SDL_KeyboardEvent event )
{
	switch(event.keysym.sym)
	{
		case SDLK_ESCAPE: exit(0);
		case SDLK_c: cam_pos = (cam_pos == CABINA)?COLA:CABINA;
	}
}


void Game::onMouseButton( SDL_MouseButtonEvent event )
{
	if (event.button == SDL_BUTTON_MIDDLE)
	{
		mouse_locked = !mouse_locked;
		SDL_ShowCursor(!mouse_locked);
	}
}
